The Python code below will load a dataset containing information about three types of Iris flowers that had the size of its petals and sepals carefully measured.
The Fisher’s Iris dataset contains 150 observations with 4 features each:
The class for each instance is stored in a separate column called “species”. In this case, the first 50 instances belong to class Setosa, the following 50 belong to class Versicolor and the last 50 belong to class Virginica.
See: https://archive.ics.uci.edu/ml/datasets/Iris for additional information.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset("iris")
iris.head()
The code below can be used to display the histogram of versicolor petal lengths (with meaningful labels for the axes and default option for number of bins).
# Set default Seaborn style
sns.set()
# Plot histogram of versicolor petal lengths
versicolor_petal_length = iris[iris.species == 'versicolor'].petal_length
plt.hist(versicolor_petal_length)
# Label axes
plt.xlabel('petal length (cm)')
plt.ylabel('count')
# Show histogram
plt.show()
Next we write code to:
The "square root rule" is a commonly-used rule of thumb for choosing number of bins: choose the number of bins to be the square root of the number of samples.
Modify the histogram above, such that the y axis shows probability/proportion (rather than absolute count), i.e., a proper PMF.
Compute summary statistics: mean and standard deviation
hist_bins=int((len(versicolor_petal_length))**(1/2))
plt.hist(versicolor_petal_length, bins=hist_bins)
# Label axes
plt.xlabel('petal length (cm)')
plt.ylabel('count')
# Show histogram
plt.show()
plt.hist(versicolor_petal_length, weights=np.ones(len(versicolor_petal_length))/len(versicolor_petal_length))
# Label axes
plt.xlabel('petal length (cm)')
plt.ylabel('Proportion of lengths')
# Show histogram
plt.show()
versicolor_petal_lengths=np.array(versicolor_petal_length)
vpl_avg=np.mean(versicolor_petal_lengths)
vpl_std=np.std(versicolor_petal_lengths)
print("Average versicolor petal length: ", vpl_avg)
print("Standard deviation of versicolor petal length: ", vpl_std)
Next we make a bee swarm plot of the iris petal lengths.
sns.swarmplot(y="petal_length", x="species", data=iris)
plt.ylabel("petal length (cm)")
plt.show()
An ideal histogram usually has a Gaussian (normal) distribution. This requires the bin width to be equal, bins not to be too wide or too narrow, and for the right number of bins to exist. For data that is not disributed in this way, a histogram may not be ideal.
When data points are very close in value, there is the potential to plot data points over each other. This would make the data difficult to visualize. A beeswarm plot solves this issue. It is used to visualize a continuous data variable such that each data point is placed at the minimum distance away from every other data point. In this way, it places emphasis on individual data points rather than binning or grouping them like a histogram. It is less ideal in situations where there is a very large amount of data, and where grouping data points close to the axis or each other does not provide an accurate representation of the data.
The function below takes as input a 1D array of data and then returns the x and y values of the ECDF.
def ecdf(data):
"""Compute ECDF for a one-dimensional array of measurements."""
# Number of data points: n
n = len(data)
# x-data for the ECDF: x
x = np.sort(data)
# y-data for the ECDF: y
y = np.arange(1, n+1) / n
return x, y
Next we use the ecdf() function above to compute the ECDF for the petal lengths of the Iris versicolor flowers and plot the resulting ECDF.
ver_x, ver_y=ecdf(versicolor_petal_lengths)
print(ver_x)
print("\n")
print(ver_y)
plt.plot(ver_x, ver_y,'.')
plt.xlabel("Petal Length (cm)")
plt.ylabel("ECDF")
plt.show()
Next we plot ECDFs for the petal lengths of all three iris species.
Your plot should look like this:
species=iris['species'].unique()
for sp in species:
slice_= iris[iris['species'] == sp].petal_length
sp_x, sp_y=ecdf(slice_)
sns.scatterplot(x=sp_x, y=sp_y, label=sp)
plt.xlabel("Petal Length (cm)")
plt.ylabel("ECDF")
plt.show()
The code below computes the 25th, 50th, and 75th percentiles for the petal lengths of the Iris versicolor species and overlays the results on top of the ECDF.
# Specify array of percentiles: percentiles
percentiles = np.array([25, 50, 75])
# Compute percentiles
ptiles_versicolor = np.percentile(versicolor_petal_length, percentiles)
# Compute ECDF
x_vers, y_vers = ecdf(versicolor_petal_length)
# Plot the ECDF
_ = plt.plot(x_vers, y_vers, '.')
_ = plt.xlabel('petal length (cm)')
_ = plt.ylabel('ECDF')
# Overlay percentiles as red diamonds.
_ = plt.plot(ptiles_versicolor, percentiles/100, marker='D', color='red',
linestyle='none')
# Show the plot
plt.show()
Next we write code to compute the 25th, 50th, and 75th percentiles for the petal lengths of and plot the resulting values overlaid with the corresponding ECDFs for all three iris species.
# Specify array of percentiles: percentiles
percentiles = np.array([25, 50, 75])
# Compute percentiles
for sp in species:
slice_= iris[iris['species'] == sp].petal_length
sp_percentiles=np.percentile(slice_, percentiles)
# Compute ECDF
sp_x, sp_y=ecdf(slice_)
# Plot the ECDF
_ = sns.scatterplot(x=sp_x, y=sp_y, label=sp)
# Overlay percentiles as red diamonds.
_ = plt.plot(sp_percentiles, percentiles/100, marker='D', color='red',
linestyle='none')
_ = plt.xlabel('petal length (cm)')
_ = plt.ylabel('ECDF')
# Show the plot
plt.show()
Box-and-whisker plots (or simply box plots) show the distribution of quantitative data in a way that facilitates comparisons between variables or across levels of a categorical variable. The box shows the quartiles of the dataset while the whiskers extend to show the rest of the distribution, except for points that are determined to be “outliers” using a method that is a function of the inter-quartile range.
Next we write code to display the box-and-whisker plot for the petal lengths of all three iris species.
sns.boxplot(x='species', y='petal_length', data=iris)
plt.xlabel("species")
plt.ylabel("petal length(cm)")
plt.show()
Virginica has the largest standard deviation. Setosa has the smallest standard deviation.
Setosa has the largest number of outliers. Virginica has the smallest number of outliers.
Next we write code to display the box-and-whisker plot combined with the bee swarm plot for the petal lengths of all three iris species.
sns.swarmplot(y="petal_length", x="species", data=iris, color='0.5')
plt.ylabel("petal length (cm)")
sns.boxplot(x='species', y='petal_length', data=iris)
plt.xlabel("species")
plt.ylabel("petal length(cm)")
plt.show()
The code below:
# Display pair plot
sns.pairplot(iris, hue='species', height=2.5);
# Compute 1D arrays for petal length and width
versicolor_petal_width = iris[iris.species == 'versicolor'].petal_width
versicolor_petal_length = iris[iris.species == 'versicolor'].petal_length
def pearson_r(x, y):
"""Compute Pearson correlation coefficient between two arrays."""
# Compute correlation matrix: corr_mat
corr_mat = np.corrcoef(x, y)
# Return entry [0,1]
return corr_mat[0,1]
# Compute Pearson correlation coefficient for I. versicolor: r
r = pearson_r(versicolor_petal_length, versicolor_petal_width)
print('Pearson correlation coefficient between petal length and petal width for versicolor species: {:.5f}'.format(r))
Next we extend the code above to compute the Pearson correlation coefficients for all pair-wise combinations of all three Iris species and display the results in a table format.
setosa=iris[iris.species=='setosa']
setosa_corr=setosa.corr(method='pearson')
print("Setosa pearson correlation: ")
setosa_corr
versicolor=iris[iris.species=='versicolor']
versicolor_corr=versicolor.corr(method='pearson')
print("Versicolor pearson correlation: ")
versicolor_corr
virginica=iris[iris.species=='virginica']
virginica_corr=virginica.corr(method='pearson')
print("Setosa pearson correlation: ")
virginica_corr